package hu.myai.indicators;

import hu.myai.api.indicators.AbstractIndicator;
import hu.myai.model.IndicatorVO;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author bozbalint
 *
 */
public class WilliamsRIndicator extends AbstractIndicator {

    /**
     * The object used when logging debug,errors,warnings and info.
     * */
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    public WilliamsRIndicator(Double parameter) {
        super(parameter);
    }

    @Override
    public void init() {
    }

    /**
     * The William's %R indicator is calculated on the following way:<br>
     * %R = (( HH - Today's Close ) / ( HH - LL )) * -100<br>
     * where:<br>
     * LL = Lowest Low price in Period<br>
     * HH = Highest High price in Period<br>
     * */

    @Override
    protected IndicatorVO indicatorCalculation() {

        if (tickHistory.size() < parameter)
            return null;

        double[] minMax = getMinMaxStock(0, parameter.intValue());

        double williansR = (minMax[1] - lastTick.getClose()) / (minMax[1] - minMax[0]) * -100;

        IndicatorVO indicator = new IndicatorVO();
        indicator.setValue(williansR);
        indicator.setChanged(true);
        indicator.setDate(lastTick.getTime());

        log.debug(indicator.toString());
        return indicator;
    }

    private double[] getMinMaxStock(int from, int to) {

        double lowerLow = tickHistory.get(from).getClose();
        double higherHigh = tickHistory.get(from).getClose();

        // get the highest and lowest value
        for (int i = (from + 1); i < to; i++) {
            double actClose = tickHistory.get(i).getClose();

            if (actClose > higherHigh)
                higherHigh = actClose;

            if (actClose < lowerLow)
                lowerLow = actClose;
        }

        double[] retValue = { lowerLow, higherHigh };
        return retValue;
    }
}
